From 7a1d8d9481bb3477b2b810693240eb72828ad275 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 29 Apr 2015 09:42:29 -0700 Subject: [PATCH] Allow more advanced filtering of what to build This commit fills out the functionality of `--lib`, `--test`, `--bin`, `--bench`, and `--example` for the `cargo {test,build,bench}` commands all at once. The support for all of this was introduced long ago, and the flags just weren't exposed at the time. --- .travis.yml | 3 ++- src/bin/bench.rs | 30 ++++++++++++++--------------- src/bin/build.rs | 24 ++++++++++++++--------- src/bin/test.rs | 35 +++++++++++++++------------------- src/cargo/ops/cargo_compile.rs | 16 ++++++++++++++++ tests/test_cargo_compile.rs | 27 ++++++++++++++++++++++++++ 6 files changed, 90 insertions(+), 45 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3aea8943f..7e4cf095f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,7 +16,8 @@ after_success: | git push -f https://${TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git gh-pages env: global: - secure: scGpeetUfba5RWyuS4yt10bPoFAI9wpHEReIFqEx7eH5vr2Anajk6+70jW6GdrWVdUvdINiArlQ3An2DeB9vEUWcBjw8WvuPtOH0tDMoSsuVloPlFD8yn1Ac0Bx9getAO5ofxqtoNg+OV4MDVuGabEesqAOWqURNrBC7XK+ntC8= + - secure: scGpeetUfba5RWyuS4yt10bPoFAI9wpHEReIFqEx7eH5vr2Anajk6+70jW6GdrWVdUvdINiArlQ3An2DeB9vEUWcBjw8WvuPtOH0tDMoSsuVloPlFD8yn1Ac0Bx9getAO5ofxqtoNg+OV4MDVuGabEesqAOWqURNrBC7XK+ntC8= + - RUST_TEST_THREADS=1 os: - linux - osx diff --git a/src/bin/bench.rs b/src/bin/bench.rs index 735b2e0d4..ec5e92722 100644 --- a/src/bin/bench.rs +++ b/src/bin/bench.rs @@ -8,11 +8,15 @@ struct Options { flag_package: Option, flag_jobs: Option, flag_features: Vec, - flag_bench: Option, flag_no_default_features: bool, flag_target: Option, flag_manifest_path: Option, flag_verbose: bool, + flag_lib: bool, + flag_bin: Vec, + flag_example: Vec, + flag_test: Vec, + flag_bench: Vec, arg_args: Vec, } @@ -24,7 +28,11 @@ Usage: Options: -h, --help Print this message - --bench NAME Name of the bench to run + --lib Benchmark only this package's library + --bin NAME Benchmark only the specified binary + --example NAME Benchmark only the specified example + --test NAME Benchmark only the specified test + --bench NAME Benchmark only the specified bench --no-run Compile, but don't run benchmarks -p SPEC, --package SPEC Package to run benchmarks for -j N, --jobs N The number of jobs to run in parallel @@ -50,11 +58,6 @@ pub fn execute(options: Options, config: &Config) -> CliResult> { let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path)); config.shell().set_verbose(options.flag_verbose); - let mut benches = Vec::new(); - if let Some(s) = options.flag_bench { - benches.push(s); - } - let ops = ops::TestOptions { no_run: options.flag_no_run, compile_opts: ops::CompileOptions { @@ -67,14 +70,11 @@ pub fn execute(options: Options, config: &Config) -> CliResult> { exec_engine: None, release: true, mode: ops::CompileMode::Bench, - filter: if benches.is_empty() { - ops::CompileFilter::Everything - } else { - ops::CompileFilter::Only { - lib: false, bins: &[], examples: &[], tests: &[], - benches: &benches, - } - }, + filter: ops::CompileFilter::new(options.flag_lib, + &options.flag_bin, + &options.flag_test, + &options.flag_example, + &options.flag_bench), }, }; diff --git a/src/bin/build.rs b/src/bin/build.rs index 4ba7de292..cb925510a 100644 --- a/src/bin/build.rs +++ b/src/bin/build.rs @@ -15,7 +15,11 @@ struct Options { flag_manifest_path: Option, flag_verbose: bool, flag_release: bool, - flag_lib: bool + flag_lib: bool, + flag_bin: Vec, + flag_example: Vec, + flag_test: Vec, + flag_bench: Vec, } pub const USAGE: &'static str = " @@ -28,7 +32,11 @@ Options: -h, --help Print this message -p SPEC, --package SPEC Package to build -j N, --jobs N The number of jobs to run in parallel - --lib Build only lib (if present in package) + --lib Build only this package's library + --bin NAME Build only the specified binary + --example NAME Build only the specified example + --test NAME Build only the specified test + --bench NAME Build only the specified benchmark --release Build artifacts in release mode, with optimizations --features FEATURES Space-separated list of features to also build --no-default-features Do not build the `default` feature @@ -63,13 +71,11 @@ pub fn execute(options: Options, config: &Config) -> CliResult> { exec_engine: None, mode: ops::CompileMode::Build, release: options.flag_release, - filter: if options.flag_lib { - ops::CompileFilter::Only { - lib: true, bins: &[], examples: &[], benches: &[], tests: &[] - } - } else { - ops::CompileFilter::Everything - }, + filter: ops::CompileFilter::new(options.flag_lib, + &options.flag_bin, + &options.flag_test, + &options.flag_example, + &options.flag_bench), }; ops::compile(&root, &opts).map(|_| None).map_err(|err| { diff --git a/src/bin/test.rs b/src/bin/test.rs index 1b09e6d2c..d46b67d44 100644 --- a/src/bin/test.rs +++ b/src/bin/test.rs @@ -8,12 +8,15 @@ struct Options { flag_features: Vec, flag_jobs: Option, flag_manifest_path: Option, - flag_test: Option, - flag_bin: Option, flag_no_default_features: bool, flag_no_run: bool, flag_package: Option, flag_target: Option, + flag_lib: bool, + flag_bin: Vec, + flag_example: Vec, + flag_test: Vec, + flag_bench: Vec, flag_verbose: bool, } @@ -25,8 +28,11 @@ Usage: Options: -h, --help Print this message - --test NAME Name of the integration test to run - --bin NAME Name of the binary to run tests for + --lib Test only this package's library + --bin NAME Test only the specified binary + --example NAME Test only the specified example + --test NAME Test only the specified integration test + --bench NAME Test only the specified benchmark --no-run Compile, but don't run tests -p SPEC, --package SPEC Package to run tests for -j N, --jobs N The number of jobs to run in parallel @@ -54,14 +60,6 @@ pub fn execute(options: Options, config: &Config) -> CliResult> { let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path)); config.shell().set_verbose(options.flag_verbose); - let (mut tests, mut bins) = (Vec::new(), Vec::new()); - if let Some(s) = options.flag_test { - tests.push(s); - } - if let Some(s) = options.flag_bin { - bins.push(s); - } - let ops = ops::TestOptions { no_run: options.flag_no_run, compile_opts: ops::CompileOptions { @@ -74,14 +72,11 @@ pub fn execute(options: Options, config: &Config) -> CliResult> { exec_engine: None, release: false, mode: ops::CompileMode::Test, - filter: if tests.is_empty() && bins.is_empty() { - ops::CompileFilter::Everything - } else { - ops::CompileFilter::Only { - lib: false, examples: &[], benches: &[], - tests: &tests, bins: &bins, - } - } + filter: ops::CompileFilter::new(options.flag_lib, + &options.flag_bin, + &options.flag_test, + &options.flag_example, + &options.flag_bench), }, }; diff --git a/src/cargo/ops/cargo_compile.rs b/src/cargo/ops/cargo_compile.rs index 0ef49cdde..9c6ba1398 100644 --- a/src/cargo/ops/cargo_compile.rs +++ b/src/cargo/ops/cargo_compile.rs @@ -184,6 +184,22 @@ pub fn compile_pkg(package: &Package, options: &CompileOptions) } impl<'a> CompileFilter<'a> { + pub fn new(lib_only: bool, + bins: &'a [String], + tests: &'a [String], + examples: &'a [String], + benches: &'a [String]) -> CompileFilter<'a> { + if lib_only || !bins.is_empty() || !tests.is_empty() || + !examples.is_empty() || !benches.is_empty() { + CompileFilter::Only { + lib: lib_only, bins: bins, examples: examples, benches: benches, + tests: tests, + } + } else { + CompileFilter::Everything + } + } + pub fn matches(&self, target: &Target) -> bool { match *self { CompileFilter::Everything => true, diff --git a/tests/test_cargo_compile.rs b/tests/test_cargo_compile.rs index 3faea78b5..0bf34c841 100644 --- a/tests/test_cargo_compile.rs +++ b/tests/test_cargo_compile.rs @@ -1654,3 +1654,30 @@ test!(dashes_in_crate_name_bad { assert_that(p.cargo_process("build").arg("-v"), execs().with_status(101)); }); + +test!(filtering { + let p = project("foo") + .file("Cargo.toml", r#" + [package] + name = "foo" + version = "0.0.1" + authors = [] + "#) + .file("src/lib.rs", "") + .file("src/bin/a.rs", "fn main() {}") + .file("src/bin/b.rs", "fn main() {}") + .file("examples/a.rs", "fn main() {}") + .file("examples/b.rs", "fn main() {}"); + p.build(); + + assert_that(p.cargo("build").arg("--lib"), + execs().with_status(0)); + assert_that(&p.bin("a"), is_not(existing_file())); + + assert_that(p.cargo("build").arg("--bin=a").arg("--example=a"), + execs().with_status(0)); + assert_that(&p.bin("a"), existing_file()); + assert_that(&p.bin("b"), is_not(existing_file())); + assert_that(&p.bin("examples/a"), existing_file()); + assert_that(&p.bin("examples/b"), is_not(existing_file())); +}); -- 2.30.2